package com.dearbinge.data.service.impl.commodity;

import com.baomidou.mybatisplus.plugins.Page;
import com.dearbinge.data.api.commodity.CommodityCommentService;
import com.dearbinge.data.dao.OrderDetailTableMapper;
import com.dearbinge.data.dao.OrderTableMapper;
import com.dearbinge.data.dao.UserMapper;
import com.dearbinge.data.dao.commodity.CommodityCommentMapper;
import com.dearbinge.data.dao.commodity.CommodityCommentPicMapper;
import com.dearbinge.data.dao.commodity.CommodityCommentShopScoreMapper;
import com.dearbinge.data.pojo.commodity.CommodityCommentDO;
import com.dearbinge.data.pojo.commodity.CommodityCommentPicDO;
import com.dearbinge.data.pojo.commodity.CommodityCommentShopScoreDO;
import com.dearbinge.data.pojo.commodity.vo.*;
import com.dearbinge.data.pojo.orderDetailTable.OrderDetailTable;
import com.dearbinge.data.pojo.orderTable.OrderTable;
import com.dearbinge.data.pojo.user.User;
import com.dearbinge.utils.*;
import com.dearbinge.utils.date.DateUtils;
import com.dearbinge.utils.enums.ResultStatusCodeEnum;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 商品评价实现层
 *
 * @author wes
 * @date 2019/3/11
 */
@Service("commodityCommentService")
public class CommodityCommentServiceImpl implements CommodityCommentService {

    @Autowired
    private CommodityCommentMapper commodityCommentMapper;
    @Autowired
    private CommodityCommentPicMapper commodityCommentPicMapper;
    @Autowired
    private OrderDetailTableMapper orderDetailTableMapper;
    @Autowired
    private OrderTableMapper orderTableMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private CommodityCommentShopScoreMapper commodityCommentShopScoreMapper;

    /**
     * 新增商品评价
     *
     * @param commodityCommentVO 商品评价接受参数 vo
     * @return 影响行数
     */
    @Override
    public ResultMsg<String> insert(CommodityCommentVO commodityCommentVO) {
        Integer orderId = commodityCommentVO.getOrderId();
        if (StringUtils.isEmpty(orderId)) {
            return ResultMsg.error(ResultStatusCodeEnum.CODE5001.getCode(), "订单号不能为空");
        }
        OrderTable orderTable = orderTableMapper.getById(orderId);
        if (orderTable == null) {
            return ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "订单号不存在");
        }
        //订单状态： 0 待付款 1 待发货 2 待收货 3 成功的订单 4关闭的订单 5.退款中
        int orderStatus = 3;
        if (orderTable.getOrderStatus() != orderStatus) {
            return ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "订单不是成功的订单，不能评价");
        }
        //是否评价（0：未评价  1：已评价 2:已追评）
        if (!orderTable.getAssessType().equals(0)) {
            return ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "订单不是未评价状态，不能评价");
        }
        String userId = orderTable.getUserId();
        ShopScoreRequestVO shopScore = commodityCommentVO.getShopScore();
        if (shopScore != null && commodityCommentShopScoreMapper.getByOrderId(orderId) == null) {
            Map<String, Object> paramMap = new HashMap<String, Object>(16);
            paramMap.put("goodsScore", shopScore.getGoodsScore());
            paramMap.put("serviceScore", shopScore.getServiceScore());
            paramMap.put("timeScore", shopScore.getTimeScore());
            Map<String, Object> checkParam = BeanValidator.checkParam(paramMap);
            if (!(boolean) checkParam.get(BeanValidator.FLAG)) {
                return ResultMsg.error(ResultStatusCodeEnum.CODE5001.getCode(), checkParam.get("name") + "参数为空");
            }
            if (shopScore.getGoodsScore() < 1 || shopScore.getServiceScore() < 1 || shopScore.getTimeScore() < 1) {
                return ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "店铺的评分不能小于1");
            }
            insertShopScore(orderId, userId, shopScore);
        }
        List<CommodityCommentRequestVO> list = commodityCommentVO.getCommodityComment();
        if (list == null) {
            return ResultMsg.error(ResultStatusCodeEnum.CODE5001.getCode(), "commodityComment 不能为空");
        }
        for (CommodityCommentRequestVO commodityCommentRequestVO : list) {
            Map<String, Object> paramMap = new HashMap<String, Object>(16);
            paramMap.put("specId", commodityCommentRequestVO.getSpecId());
            paramMap.put("anonymousStatus", commodityCommentRequestVO.getAnonymousStatus());
            paramMap.put("commentLevel", commodityCommentRequestVO.getCommentContent());
            Map<String, Object> checkParam = BeanValidator.checkParam(paramMap);
            if (!(boolean) checkParam.get(BeanValidator.FLAG)) {
                return ResultMsg.error(ResultStatusCodeEnum.CODE5001.getCode(), checkParam.get("name") + "参数为空");
            }
            CommodityCommentDO commodityCommentDO = new CommodityCommentDO();
            BeanUtils.copyProperties(commodityCommentRequestVO, commodityCommentDO);
            OrderDetailTable orderDetailTable = orderDetailTableMapper.getByOrderIdAndSpecId(orderId.toString(), commodityCommentDO.getSpecId().toString());
            if (orderDetailTable == null) {
                return ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "规格id不存在");
            }
            //订单详细 评论状态0：未评价 1：已评价 2：已回复 3：已追评 4：已追回)
            Integer commentStatus = orderDetailTable.getCommentStatus();
            if (commentStatus != 0) {
                return ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), orderDetailTable.getCommoditySpecDesc() + "这个规格不是未评价状态");
            }
            Integer commodityId = Integer.valueOf(orderDetailTable.getCommodityId());
            List<CommodityCommentPicRequestVO> commentImages = commodityCommentRequestVO.getCommentImages();
            if (commentImages != null) {
                for (CommodityCommentPicRequestVO commentImage : commentImages) {
                    String picUrl = commentImage.getPicUrl();
                    if (StringUtils.isEmpty(picUrl)) {
                        ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "图片url不能为空");
                    }
                    if (!UrlUtils.verifyUrl(picUrl)) {
                        return ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "图片url错误");
                    }
                    commentImage.setPicUrl(UrlUtils.getUrl(picUrl));
                }
            }
            insertComment(userId, commodityCommentRequestVO.getAnonymousStatus(), commodityCommentDO, orderDetailTable);
            insertPic(userId, commodityCommentDO, commodityId, commentImages);
            orderDetailTableMapper.updateCommentStatus(commentStatus + 1, orderDetailTable.getId());
            updateAssessType(orderId);
        }
        return ResultMsg.okMsg("评价成功");
    }


    /**
     * 根据商品id查商品评价
     *
     * @param commodityId 商品id
     * @param commentType 0：全部(默认)；1：好评；2：中评；3：差评；4：图片；5：追加评价
     * @param current     当前页
     * @param size        每页条数
     * @return 商品评价
     */
    @Override
    public CommodityDetailCommentVO listCommodityComment(Integer commodityId, Integer commentType, Integer current, Integer size) {
        Page page = listComment(commodityId, commentType, current, size);
        CommodityDetailCommentVO commodityDetailCommentVO = new CommodityDetailCommentVO();
        commodityDetailCommentVO.setPage(page);
        commodityDetailCommentVO.setAllTotal(commodityCommentMapper.countByCustomerIdOrCommodityId(commodityId, null, null));
        commodityDetailCommentVO.setAppendTotal(commodityCommentMapper.countByCustomerIdOrCommodityId(commodityId, null, 5));
        commodityDetailCommentVO.setImagesTotal(commodityCommentMapper.countByCustomerIdOrCommodityId(commodityId, null, 4));
        commodityDetailCommentVO.setModerateTotal(commodityCommentMapper.countByCustomerIdOrCommodityId(commodityId, null, 2));
        commodityDetailCommentVO.setNegativeTotal(commodityCommentMapper.countByCustomerIdOrCommodityId(commodityId, null, 3));
        commodityDetailCommentVO.setPositiveTotal(commodityCommentMapper.countByCustomerIdOrCommodityId(commodityId, null, 1));
        return commodityDetailCommentVO;
    }

    /**
     * 根据用户id查评价
     *
     * @param userId      用户id
     * @param commentType 0：全部(默认)；1：好评；2：中评；3：差评；4：图片；5：追加评价
     * @param current     当前页
     * @param size        每页条数
     * @return 商品评价
     */
    @Override
    public Page listMyComment(Integer userId, Integer commentType, Integer current, Integer size) {
        current = PageUtils.getDefaultValues(current, 1);
        size = PageUtils.getDefaultValues(size, 10);
        Page page = new Page(current, size);
        List<CommodityCommentDO> list = commodityCommentMapper.listByCustomerIdOrCommodityId(null, userId, commentType, page);
        List<CommodityCommentResponseVO> result = BeanMapperUtil.map(list, CommodityCommentResponseVO.class);
        for (CommodityCommentResponseVO commodityCommentResponseVO : result) {
            getImages(commodityCommentResponseVO);
            setCommodity(commodityCommentResponseVO);
            setComment(commodityCommentResponseVO);
        }
        //计算总数
        Integer total = commodityCommentMapper.countByCustomerIdOrCommodityId(null, userId, commentType);
        page.setRecords(result);
        page.setTotal(total);
        return page;
    }

    /**
     * 更新
     *
     * @param content  内容
     * @param imgArray 图片数组
     * @param type     1：商家回复；2：买家追评评论；3：商家追加回复
     * @param commodityCommentId 评论id
     * @return 成功为1
     */
    @Override
    public ResultMsg<String> update(String content, String[] imgArray, Integer type,Integer commodityCommentId) {
        CommodityCommentDO commodityComment = commodityCommentMapper.getById(commodityCommentId);
        if (commodityComment == null) {
            return ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "commodityCommentId不存在");
        }
        CommodityCommentDO commodityCommentDO = new CommodityCommentDO();
        switch (type) {
            case 1:
                //商家回复
                Date replyTime = commodityComment.getReplyTime();
                if (replyTime != null) {
                    return ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "卖家已回复，不能重复回复");
                }
                commodityCommentDO.setReplyContent(content);
                commodityCommentDO.setReplyTime(new Date());
                //修改订单表状态
                break;
            case 2:
                Date appendCommentTime = commodityComment.getAppendCommentTime();
                if (appendCommentTime != null) {
                    return  ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "买家已追评，不能重复追评");
                }
                //买家追评评论
                commodityCommentDO.setAppendCommentContent(content);
                Date now = new Date();
                commodityCommentDO.setAppendCommentTime(now);
                Date createTime = commodityComment.getCreateTime();
                int days = DateUtils.differentDaysByMillisecond(createTime, now);
                commodityCommentDO.setAppendCommentDay(days);
                if (imgArray == null) {
                    break;
                }
                for (String picUrl : imgArray) {
                    if (StringUtils.isEmpty(picUrl)) {
                        return   ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "图片url不能为空");
                    }
                    if (!UrlUtils.verifyUrl(picUrl)) {
                        return ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "图片url错误");
                    }
                    //插入
                    CommodityCommentPicDO commodityCommentPicDO = new CommodityCommentPicDO();
                    commodityCommentPicDO.setCommodityId(commodityComment.getCommodityId());
                    commodityCommentPicDO.setCommodityCommentId(commodityCommentId);
                    Integer customerId = commodityComment.getCustomerId();
                    commodityCommentPicDO.setCreateBy(customerId.toString());
                    commodityCommentPicDO.setModifyBy(customerId.toString());
                    commodityCommentPicDO.setPicPlace(2);
                    commodityCommentPicDO.setCustomerId(customerId);
                    commodityCommentPicDO.setPicUrl(UrlUtils.getUrl(picUrl));
                    commodityCommentPicMapper.insert(commodityCommentPicDO);
                }
                break;
            case 3:
                //商家追加回复
                Date appendReplyTime = commodityComment.getAppendReplyTime();
                if (appendReplyTime != null) {
                    return  ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "买家已追加回复，不能重复提交");
                }
                commodityCommentDO.setAppendReplyContent(content);
                commodityCommentDO.setAppendReplyTime(new Date());
                break;
            default:
                return ResultMsg.error(ResultStatusCodeEnum.CODE5002.getCode(), "type错误");
        }
        commodityCommentDO.setCommodityCommentId(commodityCommentId);
        int update = commodityCommentMapper.update(commodityCommentDO);
        if (update != 1) {
            ResultMsg.error(ResultStatusCodeEnum.CODE500.getCode(), "系统异常");
        }
        return ResultMsg.error(ResultStatusCodeEnum.SUCCESS.getCode(), "修改成功");
    }



    /**
     * 根据ID查询
     *
     * @param commodityCommentId 商品评论ID
     * @return vo
     */
    @Override
    public CommodityCommentResponseVO getById(Integer commodityCommentId) {
        CommodityCommentDO commodityCommentDO = commodityCommentMapper.getById(commodityCommentId);
        if (commodityCommentDO == null) {
            return null;
        }
        CommodityCommentResponseVO commodityCommentResponseVO = new CommodityCommentResponseVO();
        BeanUtils.copyProperties(commodityCommentDO, commodityCommentResponseVO);
        setComment(commodityCommentResponseVO);
        getImages(commodityCommentResponseVO);
        return commodityCommentResponseVO;
    }


    /**
     * 如果详情表都是已评价 修改订单表状态
     *
     * @param orderId 订单id
     */
    private void updateAssessType(Integer orderId) {
        boolean flag = true;
        List<OrderDetailTable> listOrderDetail = orderDetailTableMapper.listByOrderId(orderId);
        for (OrderDetailTable detailTable : listOrderDetail) {
            Integer status = detailTable.getCommentStatus();
            if (status == 0) {
                flag = false;
            }
        }
        if (flag) {
            orderTableMapper.updateAssessType(1, orderId);
        }
    }

    private void insertPic(String userId, CommodityCommentDO commodityCommentDO, Integer commodityId, List<CommodityCommentPicRequestVO> commentImages) {
        if (commentImages != null) {
            for (CommodityCommentPicRequestVO commentImage : commentImages) {
                CommodityCommentPicDO commodityCommentPicDO = new CommodityCommentPicDO();
                BeanUtils.copyProperties(commentImage, commodityCommentPicDO);
                commodityCommentPicDO.setCommodityId(commodityId);
                commodityCommentPicDO.setCommodityCommentId(commodityCommentDO.getCommodityCommentId());
                commodityCommentPicDO.setCreateBy(userId);
                commodityCommentPicDO.setModifyBy(userId);
                commodityCommentPicDO.setPicPlace(1);
                commodityCommentPicDO.setCustomerId(Integer.valueOf(userId));
                commodityCommentPicMapper.insert(commodityCommentPicDO);
            }
        }
    }

    private void insertShopScore(Integer orderId, String userId, ShopScoreRequestVO shopScore) {
        CommodityCommentShopScoreDO commodityCommentShopScoreDO = new CommodityCommentShopScoreDO();
        BeanUtils.copyProperties(shopScore, commodityCommentShopScoreDO);
        commodityCommentShopScoreDO.setOrderId(orderId);
        commodityCommentShopScoreDO.setCustomerId(Integer.valueOf(userId));
        commodityCommentShopScoreDO.setCreateBy(userId);
        commodityCommentShopScoreDO.setModifyBy(userId);
        commodityCommentShopScoreMapper.insert(commodityCommentShopScoreDO);
    }

    private void insertComment(String userId, Boolean anonymousStatus, CommodityCommentDO commodityCommentDO,
                               OrderDetailTable orderDetailTable) {
        //封装必要的参数
        String commoditySpecDesc = orderDetailTable.getCommoditySpecDesc();
        String commodityId = orderDetailTable.getCommodityId();
        Integer orderId = orderDetailTable.getOrderId();
        commodityCommentDO.setCommodityId(Integer.valueOf(commodityId));
        commodityCommentDO.setCommoditySpec(commoditySpecDesc);
        //现在默认通过审核
        User user = userMapper.getById(Integer.valueOf(userId));
        commodityCommentDO.setAuditStatus(true);
        commodityCommentDO.setCustomerId(Integer.valueOf(userId));
        commodityCommentDO.setCreateBy(userId);
        commodityCommentDO.setModifyBy(userId);
        commodityCommentDO.setOrderId(orderId);
        String userName = Base64Util.decodeData(user.getName());
        //匿名 将名字 中间换成星星
        if (anonymousStatus && userName != null) {
            userName = nameHidden(userName);
        }
        commodityCommentDO.setCustomerName(userName);
        commodityCommentMapper.insert(commodityCommentDO);
    }


    private Page listComment(Integer commodityId, Integer commentType, Integer current, Integer size) {
        current = PageUtils.getDefaultValues(current, 1);
        size = PageUtils.getDefaultValues(size, 10);
        Page page = new Page(current, size);
        List<CommodityCommentDO> list = commodityCommentMapper.listByCustomerIdOrCommodityId(commodityId, null, commentType, page);
        List<CommodityCommentResponseVO> result = BeanMapperUtil.map(list, CommodityCommentResponseVO.class);
        for (CommodityCommentResponseVO commodityCommentResponseVO : result) {
            getImages(commodityCommentResponseVO);
            setComment(commodityCommentResponseVO);
        }
        //计算总数
        Integer total = commodityCommentMapper.countByCustomerIdOrCommodityId(commodityId, null, commentType);
        page.setRecords(result);
        page.setTotal(total);
        return page;
    }


    private void getImages(CommodityCommentResponseVO commodityCommentResponseVO) {
        User user = userMapper.getById(commodityCommentResponseVO.getCustomerId());
        commodityCommentResponseVO.setHeadImg(user.getHeadImg());
        Integer commodityCommentId = commodityCommentResponseVO.getCommodityCommentId();
        int picPlace = 1;
        List<CommodityCommentPicResponseVO> commentImages = getPicUrl(commodityCommentId, picPlace);
        commodityCommentResponseVO.setCommentImages(commentImages);
        if (commodityCommentResponseVO.getAppendCommentTime() != null) {
            picPlace = 2;
            List<CommodityCommentPicResponseVO> appendCommentImages = getPicUrl(commodityCommentId, picPlace);
            commodityCommentResponseVO.setAppendCommentImages(appendCommentImages);
        }
    }

    private List<CommodityCommentPicResponseVO> getPicUrl(Integer commodityCommentId, int picPlace) {
        List<CommodityCommentPicDO> comment = commodityCommentPicMapper.listByCommodityCommentId(commodityCommentId, picPlace);
        if (comment == null || comment.size() == 0) {
            return null;
        }
        List<CommodityCommentPicResponseVO> map = BeanMapperUtil.map(comment, CommodityCommentPicResponseVO.class);
        //拼接ip地址
        for (CommodityCommentPicResponseVO commodityCommentPicResponseVO : map) {
            String address = AddressUtil.spliceAddress(commodityCommentPicResponseVO.getPicUrl());
            commodityCommentPicResponseVO.setPicUrl(address);
        }
        return map;
    }

    private void setComment(CommodityCommentResponseVO commodityCommentResponseVO) {
        if (commodityCommentResponseVO.getCommentContent() == null) {
            commodityCommentResponseVO.setCommentContent("此用户没有填写评价");
        }
    }




    /**
     * 处理匿名
     *
     * @param name 名字
     * @return 匿名结果
     */
    private static String nameHidden(String name) {
        char[] names = name.toCharArray();
        for (int i = 1; i < names.length; i++) {
            names[i] = '*';
        }
        return String.valueOf(names);
    }



    private void setCommodity(CommodityCommentResponseVO commodityCommentResponseVO) {
        Integer orderId = commodityCommentResponseVO.getOrderId();
        Integer specId = commodityCommentResponseVO.getSpecId();
        OrderDetailTable orderDetailTable = orderDetailTableMapper.getByOrderIdAndSpecId(orderId.toString(), specId.toString());
        OrderTable orderTable = orderTableMapper.getById(orderId);
        if (orderDetailTable == null || orderTable == null) {
            return;
        }
        CommoditySimpleParamVO commoditySimpleParamVO = new CommoditySimpleParamVO();
        commoditySimpleParamVO.setCommodityName(orderDetailTable.getCommodityName());
        commoditySimpleParamVO.setImgUrl(orderDetailTable.getSotreimg());
        commoditySimpleParamVO.setRetailPrice(orderDetailTable.getPrimaryPrice());
        commoditySimpleParamVO.setCommodityShopId(orderTable.getShopId());
        commodityCommentResponseVO.setCommoditySimpleParamVO(commoditySimpleParamVO);
    }
}
